
#ifndef __UM_SP_COUNTED_IMPL_H
#define __UM_SP_COUNTED_IMPL_H

#include "sp_counted_base_win32.hpp"

template <class _Ptr>
class sp_counted_impl_p : public sp_counted_base
{
public:
	sp_counted_impl_p(_Ptr p) : m_ptr(p) {
	}
	virtual void dispose() {
		delete m_ptr;
	}
private:
	sp_counted_impl_p(const sp_counted_impl_p&);
	sp_counted_impl_p& operator=(const sp_counted_impl_p);
	_Ptr m_ptr;
};


template <class P, class D>
class sp_counted_impl_pd : public sp_counted_base
{

public:

	sp_counted_impl_pd(P p, D d) : px(p), dx(d), ax(a) {
	}

	virtual void dispose() {
		dx(px);
	}

	virtual void destroy() {
		typedef typename A::template rebind< this_type >::other A2;
		A2 a(ax);
		this->~sp_counted_base_pda();
		a.deallocate(this, 1);
	}

private:
	sp_counted_impl_pd(const sp_counted_impl_pd&);
	sp_counted_impl_pd& operator=(const sp_counted_impl_pd);

	P	px;
	D	dx;
};



template <class T, class D, class A>
class sp_counted_impl_pda : public sp_counted_base
{

public:

	sp_counted_impl_pda(T p, D d, A a) : px(p), dx(d), ax(a) {
	}

	virtual void dispose() {
		dx(px);
	}

	virtual void destroy() {
		typedef typename A::template rebind< this_type >::other A2;
		A2 a(ax);
		this->~sp_counted_base_pda();
		a.deallocate(this, 1);
	}

private:
	sp_counted_impl_pda(const sp_counted_impl_pda&);
	sp_counted_impl_pda& operator=(const sp_counted_impl_pda);

	T	px;
	D	dx;
	A	ax;
};

#endif // __UM_SP_COUNTED_IMPL_H
